#ifndef _TEST_PREDICATE_H_
#define _TEST_PREDICATE_H_
#include <cppunit/extensions/HelperMacros.h>
class Test_predicate : public CppUnit::TestFixture
{
	CPPUNIT_TEST_SUITE (Test_predicate);

	// Test with triangles. 
	CPPUNIT_TEST (test_pol_pol_01);
	CPPUNIT_TEST (test_pol_pol_02);
	CPPUNIT_TEST (test_pol_pol_03);
	CPPUNIT_TEST (test_pol_pol_04);
	CPPUNIT_TEST (test_pol_pol_05);
	CPPUNIT_TEST (test_pol_pol_06);
	CPPUNIT_TEST (test_pol_pol_07);
	CPPUNIT_TEST (test_pol_pol_08);
	CPPUNIT_TEST (test_pol_pol_09);
	CPPUNIT_TEST (test_pol_pol_10);

	// Test with polygons. 
	/*
	CPPUNIT_TEST (test_pol_pol_11);
	CPPUNIT_TEST (test_pol_pol_12);
	CPPUNIT_TEST (test_pol_pol_13);
	CPPUNIT_TEST (test_pol_pol_14);
	CPPUNIT_TEST (test_pol_pol_15);
	CPPUNIT_TEST (test_pol_pol_16);
	CPPUNIT_TEST (test_pol_pol_17);
	CPPUNIT_TEST (test_pol_pol_18);
	CPPUNIT_TEST (test_pol_pol_19);
	CPPUNIT_TEST (test_pol_pol_20);
	*/
	CPPUNIT_TEST_SUITE_END();

public :
	void setUp(){}
	void tearDown(){}

	/**
	 * Co-planar triangles. Vertex intersects vertex. 
	 */
	void test_pol_pol_01()
	{
		Vector<Value> p1, q1, r1 ;  // First triangle. 
		Vector<Value> p2, q2, r2 ;  // Second triangle. 

		p1 = Vector<Value> (Value (0.0), Value(1.0), Value(1e-54));
		q1 = Vector<Value> (Value (1.0), Value(1.0), Value(1e-54));
		r1 = Vector<Value> (Value (1.718281828e-54), Value(0.103), Value(1e-54));

		p2 = Vector<Value> (Value (-1.0), Value(0.0), Value(1e-54));
		q2 = Vector<Value> (Value (1.718281828e-54), Value(0.103), Value(1e-54));
		r2 = Vector<Value> (Value (-1.0), Value(-1.0), Value(1e-54));

		PolygonType polygon1 , polygon2 ;
		polygon1.append_vertex(p1); 
		polygon1.append_vertex(q1); 
		polygon1.append_vertex(r1);

		polygon2.append_vertex(p2); 
		polygon2.append_vertex(q2); 
		polygon2.append_vertex(r2);

		CPPUNIT_ASSERT (true == predicate_polygon_polygon (polygon1, polygon2 ));
	}
	/**
	 * Co-planar triangles. Vertex intersects vertex. Silver triangles. 
	 */
	void test_pol_pol_02()
	{
		Vector<Value> p1, q1, r1 ;  // First triangle. 
		Vector<Value> p2, q2, r2 ;  // Second triangle. 

		p1 = Vector<Value> (Value (0.0), Value(1.0), Value(1e54));
		q1 = Vector<Value> (Value (1.0), Value(1.0), Value(1e54));
		r1 = Vector<Value> (Value (1.718281828e-54), Value(1.03e128), Value(1e54));

		p2 = Vector<Value> (Value (-1.0), Value(0.0), Value(1e54));
		q2 = Vector<Value> (Value (1.718281828e-54), Value(1.03e128), Value(1e54));
		r2 = Vector<Value> (Value (-1.0), Value(-1.0), Value(1e54));

		PolygonType polygon1 , polygon2 ;
		polygon1.append_vertex(p1); 
		polygon1.append_vertex(q1); 
		polygon1.append_vertex(r1);

		polygon2.append_vertex(p2); 
		polygon2.append_vertex(q2); 
		polygon2.append_vertex(r2);

		CPPUNIT_ASSERT (true == predicate_polygon_polygon (polygon1, polygon2 ));
	}
    /**
	 * Co-planar triangles. Vertex intersects vertex.  Circulate triangle vertex. 
	 */
	void test_pol_pol_03()
	{
		Vector<Value> p1, q1, r1 ;  // First triangle. 
		Vector<Value> p2, q2, r2 ;  // Second triangle. 

		p1 = Vector<Value> (Value (0.0), Value(1.0), Value(1e54));
		q1 = Vector<Value> (Value (1.0), Value(1.0), Value(1e54));
		r1 = Vector<Value> (Value (1.718281828e-54), Value(1.03e128), Value(1e54));

		p2 = Vector<Value> (Value (-1.0), Value(0.0), Value(1e54));
		q2 = Vector<Value> (Value (1.718281828e-54), Value(1.03e128), Value(1e54));
		r2 = Vector<Value> (Value (-1.0), Value(-1.0), Value(1e54));

		PolygonType polygon1 , polygon2 ;
		polygon1.append_vertex(p1); polygon1.append_vertex(q1); polygon1.append_vertex(r1);
		polygon2.append_vertex(p2); polygon2.append_vertex(q2); polygon2.append_vertex(r2);
		CPPUNIT_ASSERT (true == predicate_polygon_polygon (polygon1, polygon2 ));		

		PolygonType polygon3 ; 
		polygon3.append_vertex(q2); polygon3.append_vertex(r2); polygon3.append_vertex(p2);  
		CPPUNIT_ASSERT (true == predicate_polygon_polygon (polygon1, polygon3 ));		

		PolygonType polygon4 ; 
		polygon4.append_vertex(r2); polygon4.append_vertex(p2); polygon4.append_vertex(q2);  
		CPPUNIT_ASSERT (true == predicate_polygon_polygon (polygon1, polygon4 ));		
	}

	/**
	 * Co-planar triangles. None-intersect. 
	 */
	void test_pol_pol_04()
	{
		Vector<Value> p1, q1, r1 ;  // First triangle. 
		Vector<Value> p2, q2, r2 ;  // Second triangle. 

		p1 = Vector<Value> (Value (0.0), Value(1.0), Value(1e54));
		q1 = Vector<Value> (Value (1.0), Value(1.0), Value(1e54));
		r1 = Vector<Value> (Value (1.123456789e-54), Value(1.03e128), Value(1e54));

		p2 = Vector<Value> (Value (-1.0), Value(0.0), Value(1e54));
		q2 = Vector<Value> (Value (1.123456788e-54), Value(1.03e-128), Value(1e54));
		r2 = Vector<Value> (Value (-1.0), Value(-1.0), Value(1e54));

		PolygonType polygon1 , polygon2 ;
		polygon1.append_vertex(p1); 
		polygon1.append_vertex(q1); 
		polygon1.append_vertex(r1);

		polygon2.append_vertex(p2); 
		polygon2.append_vertex(q2); 
		polygon2.append_vertex(r2);

		CPPUNIT_ASSERT (false == predicate_polygon_polygon (polygon1, polygon2 ));
	}

	/**
	 * Non-intersect triangle. Parallel. One is above the other along z-axis. 
	 */
	void test_pol_pol_05()
	{
		Vector<Value> p1, q1, r1 ;  // First triangle. 
		Vector<Value> p2, q2, r2 ;  // Second triangle. 

		p1 = Vector<Value> (Value (0.0), Value(1.0e54), Value(1e-54));
		q1 = Vector<Value> (Value (1.0e54), Value(1.0e54), Value(1e-54));
		r1 = Vector<Value> (Value (1.123456789e-54), Value(1.03e128), Value(1e-54));

		p2 = Vector<Value> (Value (0.0), Value(1.0e54), Value(-1e-54));
		q2 = Vector<Value> (Value (1.0e54), Value(1.0e54), Value(-1e-54));
		r2 = Vector<Value> (Value (1.123456789e-54), Value(1.03e128), Value(-1e-54));


		PolygonType polygon1 , polygon2 ;
		polygon1.append_vertex(p1); 
		polygon1.append_vertex(q1); 
		polygon1.append_vertex(r1);

		polygon2.append_vertex(p2); 
		polygon2.append_vertex(q2); 
		polygon2.append_vertex(r2);

		CPPUNIT_ASSERT (false == predicate_polygon_polygon (polygon1, polygon2 ));
	}

    /**
     * Non-coplanar triangles. Vertex intersect vertex. 
     * The intersection point is (1.718281828e-54, 0.103, 0);
     */
	void test_pol_pol_06()
	{
		Vector<Value> p1, q1, r1 ;  // First triangle. 
		Vector<Value> p2, q2, r2 ;  // Second triangle. 

		p1 = Vector<Value> (Value (0.0), Value(1.0), Value(1e-54));
		q1 = Vector<Value> (Value (1.0), Value(1.0), Value(1e-54));
		r1 = Vector<Value> (Value (1.718281828e-54), Value(0.103), Value(0.0));

		p2 = Vector<Value> (Value (-1.0), Value(0.0), Value(0.0));
		q2 = Vector<Value> (Value (1.718281828e-54), Value(0.103), Value(0.0));
		r2 = Vector<Value> (Value (-1.0), Value(-1.0), Value(0.0));

		PolygonType polygon1 , polygon2 ;
		polygon1.append_vertex(p1); 
		polygon1.append_vertex(q1); 
		polygon1.append_vertex(r1);

		polygon2.append_vertex(p2); 
		polygon2.append_vertex(q2); 
		polygon2.append_vertex(r2);

		CPPUNIT_ASSERT (true == predicate_polygon_polygon (polygon1, polygon2 ));
	}

    /**
     * Non-coplanar triangles. Vertex intersect vertex. 
     * The intersection point is (1.718281828e-54, 0.103, 0);
     */
	void test_pol_pol_07()
	{
		Vector<Value> p1, q1, r1 ;  // First triangle. 
		Vector<Value> p2, q2, r2 ;  // Second triangle. 

		p1 = Vector<Value> (Value (0.0), Value(1.0), Value(1e-54));
		q1 = Vector<Value> (Value (1.0), Value(1.0), Value(1e-54));
		r1 = Vector<Value> (Value (1.718281828e-54), Value(0.103), Value(0.0));

		p2 = Vector<Value> (Value (0.0), Value(1.0), Value(0));
		q2 = Vector<Value> (Value (1.0), Value(1.0), Value(0));
		r2 = Vector<Value> (Value (1.718281828e-54), Value(0.103), Value(0.0));


		PolygonType polygon1 , polygon2 ;
		polygon1.append_vertex(p1); 
		polygon1.append_vertex(q1); 
		polygon1.append_vertex(r1);

		polygon2.append_vertex(p2); 
		polygon2.append_vertex(q2); 
		polygon2.append_vertex(r2);

		CPPUNIT_ASSERT (true == predicate_polygon_polygon (polygon1, polygon2 ));
	}

	/**
	 * Non-coplanar triangles. Vertex intersect vertex silver triangles. 
	 */
	void test_pol_pol_08()
	{
		Vector<Value> p1, q1, r1 ;  // First triangle. 
		Vector<Value> p2, q2, r2 ;  // Second triangle. 

		p1 = Vector<Value> (Value (0.0), Value(1e-54), Value(1e128));
		q1 = Vector<Value> (Value (1e-54), Value(-1e-54), Value(0.0));
		r1 = Vector<Value> (Value (2e-54), Value(1e103), Value(0.0));

		p2 = Vector<Value> (Value (2e-54), Value(1e103), Value(0));
		q2 = Vector<Value> (Value (3e-54), Value(1e-54), Value(0));
		r2 = Vector<Value> (Value (4e-54), Value(-1e-54), Value(0.0));


		PolygonType polygon1 , polygon2 ;
		polygon1.append_vertex(p1); 
		polygon1.append_vertex(q1); 
		polygon1.append_vertex(r1);

		polygon2.append_vertex(p2); 
		polygon2.append_vertex(q2); 
		polygon2.append_vertex(r2);

		CPPUNIT_ASSERT (true == predicate_polygon_polygon (polygon1, polygon2 ));
	}

	/**
	 * Co-planar triangles. Vertex intersect edges. 
	 */
	void test_pol_pol_09()
	{
		Vector<Value> p1, q1, r1 ;  // First triangle. 
		Vector<Value> p2, q2, r2 ;  // Second triangle. 

		p1 = Vector<Value> (Value (0.0), Value(1e-54), Value(1e128));
		q1 = Vector<Value> (Value (1e-54), Value(1e-54), Value(1e128));
		r1 = Vector<Value> (Value (2e-54), Value(1e103), Value(1e128));

		p2 = Vector<Value> (Value (0.5e-54), Value(1e-54), Value(1e128));
		q2 = Vector<Value> (Value (3e-54), Value(-1e-54), Value(1e128));
		r2 = Vector<Value> (Value (4e-54), Value(-1e-54), Value(1e128));


		PolygonType polygon1 , polygon2 ;
		polygon1.append_vertex(p1); 
		polygon1.append_vertex(q1); 
		polygon1.append_vertex(r1);

		polygon2.append_vertex(p2); 
		polygon2.append_vertex(q2); 
		polygon2.append_vertex(r2);

		CPPUNIT_ASSERT (true == predicate_polygon_polygon (polygon1, polygon2 ));
	}

	/**
	 * Non-co-planar triangles. Vertex intersect edges. 
	 */
	void test_pol_pol_10()
	{
		Vector<Value> p1, q1, r1 ;  // First triangle. 
		Vector<Value> p2, q2, r2 ;  // Second triangle. 

		p1 = Vector<Value> (Value (0.0), Value(1e-54), Value(1e128));
		q1 = Vector<Value> (Value (1e-54), Value(1e-54), Value(1e128));
		r1 = Vector<Value> (Value (2e-54), Value(1e103), Value(1e128));

		p2 = Vector<Value> (Value (0.5e-54), Value(1e-54), Value(1e128));
		q2 = Vector<Value> (Value (3e-54), Value(-1e-54), Value(1e128));
		r2 = Vector<Value> (Value (4e-54), Value(-1e-54), Value(1e-128));


		PolygonType polygon1 , polygon2 ;
		polygon1.append_vertex(p1); 
		polygon1.append_vertex(q1); 
		polygon1.append_vertex(r1);

		polygon2.append_vertex(p2); 
		polygon2.append_vertex(q2); 
		polygon2.append_vertex(r2);

		CPPUNIT_ASSERT (true == predicate_polygon_polygon (polygon1, polygon2 ));
	}

private:

};

CPPUNIT_TEST_SUITE_REGISTRATION (Test_predicate);

#endif
